package com.yun.yun;

import android.content.Context;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.example.icreader.NativeReader;

import java.io.UnsupportedEncodingException;

public class CpuIdReaderHelper {

    private static CpuIdReaderHelper instance;



    public synchronized static CpuIdReaderHelper getInstance() {
        if (instance == null) {
            instance = new CpuIdReaderHelper();
        }
        return instance;
    }

    private static UsbDeviceHelper g_usbHelp;
    private int m_DevFD;//设备描述符
    private int m_DevType = 0;
    private  String sfzpath;

    private ReaderListener mReaderListener;

    public interface ReaderListener {
        void onIdReaderSuccess(String data);
        void onCpuReaderSuccess(String data);
    }

//    public void setReaderListener(ReaderListener mReaderListener) {
//        this.mReaderListener = mReaderListener;
//    }


    public String openDev(Context context,ReaderListener mReaderListener) {
        this.mReaderListener = mReaderListener;
        g_usbHelp = new UsbDeviceHelper(context);
        sfzpath = context.getCacheDir().getAbsolutePath() + "/zp.bmp";

        //外设必须授权才能打开设备
        if (NativeReader.icdev > 0){
            NativeReader.ICReaderClose(NativeReader.icdev);
        }
        int ret = 0;
        int OpenType = 0;
        int vid = 0x5929,pid = 0x68A6;
//        String strtype =  m_comType.getSelectedItem().toString().trim();
//        String strdevpath = m_DevPath.getSelectedItem().toString().trim();
        byte[] devPath = new byte[0];
//        if(strtype.equals("COM")){
//            devPath = strdevpath.getBytes();
//            int baud = Integer.valueOf(m_comBaud.getSelectedItem().toString());
//            ret = NativeReader.ICReaderOpenComBypath(devPath,baud);
//            m_DevFD = ret;
//        }else{
            //usb选项
            vid = 0x5929;
            pid = 0x68A6;
            m_DevFD = g_usbHelp.getUsbFileDescriptor(vid, pid);
            if(m_DevFD < 0){
                m_DevFD = g_usbHelp.getUsbFileDescriptor(vid, pid);
            }

            if(m_DevFD < 0){
                vid = 0x23A4;
                pid = 0x0219;
                m_DevFD = g_usbHelp.getUsbFileDescriptor(vid,pid);
                if (m_DevFD < 0) {
                    m_DevFD = g_usbHelp.getUsbFileDescriptor(vid,pid);
                }
            }
            if(m_DevFD<=0){
//                ShowTips(1,"获取设备描述符失败,return = " + m_DevFD);
                Log.d("MainActivity","获取设备描述符失败,return = " + m_DevFD);
                return "failed";
                //m_DevFD = 0;
            }
                /*
                 # 转换为Permissive宽容模式  setenforce  0
                 # 转换为Enforcing强制模式  setenforce  1
                注意事项：setenforce无法设置SELinux为Disabled模式(关闭模式。SELinux并没有实际运行)
                 */
            //获取设备SELinux运行是否为强制模式
            String mode = ShellExecute.getSELinuxMode().trim();
            //强制模式下正确开始限制domain/type
//            ShowTips(1,"SELinux:" + mode);

            devPath = g_usbHelp.getUsbDevPath().getBytes();
            //fd 打开失败时候，内部会关闭句柄, 必须重新获取
            if(mode.equals("Enforcing") || m_DevType > 0){
//                ShowTips(1,"Mount path:" + g_usbHelp.getUsbDevPath());
                ret = NativeReader.ICReaderOpenUsbByPathEx(m_DevFD,devPath,vid,pid); //ICReaderOpenUsbByPath 弃用
                OpenType = 1;
                Log.d("MainActivity", "ICReaderOpenUsbByPathEx");
            }else {
                //Permissive模式下，fd 不在安卓端打开，直接使用0某些安卓系统也可以兼容打开，不需要外面再给设备描述符;（具体跟安卓系统有关系）
                ret = NativeReader.ICReaderOpenUsbByFD(m_DevFD); //
                Log.d("MainActivity", "ICReaderOpenUsbByFD");
                //if (ret == -97){
                //SELinux 为空情况下有时需要通过路径和FD才能打开
                //ret = NativeReader.ICReaderOpenUsbByPathEx(m_DevFD,devPath,vid,pid);
                //Log.d("MainActivity", "ICReaderOpenUsbByPathEx");
                //}
                OpenType = 0;
            }
//        }
        if(ret >= 0){
            Log.v("MainActivity","打开设备成功,icdev = " + m_DevFD);

//            ShowTips(1, "打开设备成功,icdev = " + m_DevFD);
            Log.d("MainActivity", "打开设备成功");
            NativeReader.icdev = ret;
            //读版本号，序列号，测试蜂鸣响一声
            byte[] pVer = new byte[64];
            ret = NativeReader.ICReaderGetVer(NativeReader.icdev,pVer);
            if(ret == 0)
            {
                //版本号显示
                byte[] pSN = new byte[128];
                NativeReader.ICReaderReadDevSnr(NativeReader.icdev,20,pSN);
                NativeReader.ICReaderBeep(NativeReader.icdev,1,1,1);
                Log.v("MainActivity","设备版本号为：" +  new String(pVer).trim() + ",设备序列号为:" + new String(pSN).trim());
//                ShowTips(1,"设备版本号为：" +  new String(pVer).trim() + ",设备序列号为:" + new String(pSN).trim());
            }
            m_DevType = OpenType;
            readIDCard(context);
        }else{
//            if(false == strtype.equals("COM")){
//                if(m_DevFD > 0 && OpenType == 0)
//                    m_DevType = 1;
//                else if(m_DevFD > 0 && OpenType == 1)
//                    m_DevType = 0;
//                else
//                    m_DevType = 0;
//            }
//            ShowTips(1, "打开设备失败,返回值:" + ret);
            Toast.makeText(context,"身份证模块打开失败",Toast.LENGTH_LONG).show();

            Log.d("MainActivity", "打开设备失败:" + ret);
        }
        return "success";
    }


    public void readIDCard(Context context){
        Log.d("MainActivity","readIDCard");
        new Thread(() -> {
            int iSlot = 0x31;
            //public static native int ReadSIIssuerInfo(int icdev, int uSlot,byte[] pData);
            byte[] pData = new byte[256];

            int iFlag = 0;
            byte[] pucCHMsg = new byte[260];//文字
            byte[] pucPHMsg = new byte[1032];//照片
            byte[] pucFPMsg = new byte[1032];//指纹
            int[] puiCHMsgLen = new int[1];//文字
            int[] puiPHMsgLen = new int[1];//照片
            int[] puiFPMsgLen = new int[1];//指纹
            IDCardMsg idinfo = new IDCardMsg();
            int ret = -1;
            while (ret != 0){
                ret = NativeReader.ReadSIIssuerInfo(NativeReader.icdev,iSlot,pData);
                Log.d("MainActivity","ret:" + ret);
                if(ret != 0){
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    Log.d("MainActivity","读社保卡失败");
                    ret = NativeReader.ReadIDCardBaseMsg(NativeReader.icdev,iFlag,pucCHMsg,puiCHMsgLen,pucPHMsg,
                            puiPHMsgLen,pucFPMsg,puiFPMsgLen);
                    Log.d("MainActivity","ret:" + ret);
                    if(ret == 0){
                        ret = idinfo.ParseIDMsg(pucCHMsg,puiCHMsgLen[0]);
                        if(ret == 0) {
                            //文字解析成功
                            String chmsg = "";
                            if(idinfo.getIDType().equals("I") || idinfo.getIDType().equals("Y")){
                                //2017版外国人永久居留证 新版外国人永久居留证
                                chmsg = idinfo.getEngName() + "|" + idinfo.getSex() + "|" + idinfo.getID() + "|"
                                        + idinfo.getNationality()+ "|"  + idinfo.getName() + "|" + idinfo.getStartDate() + "|"
                                        + idinfo.getEndDate() + "|" + idinfo.getBirthday() + "|" +idinfo.getSignNum()+ "|"
                                        + idinfo.getIssue() + "|" + idinfo.getReverse() + "|" + idinfo.getIDNum() + "|";
                            }else if(idinfo.getIDType().equals("J")){
                                //港澳台
                                chmsg = idinfo.getName() + "|" + idinfo.getSex() + "|"
                                        + idinfo.getBirthday() + "|" + idinfo.getAddr()+ "|"  + idinfo.getID() + "|"
                                        + idinfo.getIssue() + "|" + idinfo.getStartDate() + idinfo.getEndDate() + "|" + idinfo.getPassID() + "|"
                                        + idinfo.getSignNum() +  "|" + idinfo.getReverse();
                            }else{
                                //身份证
                                chmsg = idinfo.getName() + "|" + idinfo.getSex() + "|"  + idinfo.getNation() + "|"
                                        + idinfo.getBirthday() + "|" + idinfo.getAddr()+ "|"  + idinfo.getID() + "|"
                                        + idinfo.getIssue() + "|" + idinfo.getStartDate() +  "|"  +idinfo.getEndDate() + "|" + idinfo.getReverse();
                            }
                            //显示
                            Log.d("MainActivity","该身份证信息为:" + chmsg);
                            mReaderListener.onIdReaderSuccess(chmsg);

                        }else{
                            //文字解析失败
                            Toast.makeText(context,"身份证解析失败",Toast.LENGTH_LONG).show();
                            Log.d("MainActivity","文字解析失败:" + ret);
                        }
                    }else{
                        Log.d("MainActivity","读身份证失败");

                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }else{
//                    String rDataE5 = null;
                    try {
                        String rDataE5 = new String(pData,"gb18030").trim();
                        //显示
                        Log.d("MainActivity","EF05:" + rDataE5);
                        byte[] pData2 = new byte[256];
//                        stime = SystemClock.uptimeMillis();
                        ret = NativeReader.ReadSIPersonalInfo(NativeReader.icdev,iSlot,pData2);
//                        stime = SystemClock.uptimeMillis() - stime;
                        if(ret == 0)
                        {
                            String rDataE6 = null;
                            try {
                                rDataE6 = new String(pData2,"gb18030").trim();
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                            Log.d("MainActivity","EF06:" + rDataE6);
                            mReaderListener.onCpuReaderSuccess(rDataE5+rDataE6);
                        }else {
                            Log.d("MainActivity","读社保卡失败");

                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }

                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }
            }

//            ret = idinfo.ParseIDMsg(pucCHMsg,puiCHMsgLen[0]);
//            if(ret == 0) {
//                //文字解析成功
//                String chmsg = "";
//                if(idinfo.getIDType().equals("I") || idinfo.getIDType().equals("Y")){
//                    //2017版外国人永久居留证 新版外国人永久居留证
//                    chmsg = idinfo.getEngName() + "|" + idinfo.getSex() + "|" + idinfo.getID() + "|"
//                            + idinfo.getNationality()+ "|"  + idinfo.getName() + "|" + idinfo.getStartDate() + "|"
//                            + idinfo.getEndDate() + "|" + idinfo.getBirthday() + "|" +idinfo.getSignNum()+ "|"
//                            + idinfo.getIssue() + "|" + idinfo.getReverse() + "|" + idinfo.getIDNum() + "|";
//                }else if(idinfo.getIDType().equals("J")){
//                    //港澳台
//                    chmsg = idinfo.getName() + "|" + idinfo.getSex() + "|"
//                            + idinfo.getBirthday() + "|" + idinfo.getAddr()+ "|"  + idinfo.getID() + "|"
//                            + idinfo.getIssue() + "|" + idinfo.getStartDate() + idinfo.getEndDate() + "|" + idinfo.getPassID() + "|"
//                            + idinfo.getSignNum() +  "|" + idinfo.getReverse();
//                }else{
//                    //身份证
//                    chmsg = idinfo.getName() + "|" + idinfo.getSex() + "|"  + idinfo.getNation() + "|"
//                            + idinfo.getBirthday() + "|" + idinfo.getAddr()+ "|"  + idinfo.getID() + "|"
//                            + idinfo.getIssue() + "|" + idinfo.getStartDate() +  "|"  +idinfo.getEndDate() + "|" + idinfo.getReverse();
//                }
//                //显示
//                Log.d("MainActivity","该身份证信息为:" + chmsg);
//                mReaderListener.onReaderSuccess(chmsg);
//
//            }else{
//                //文字解析失败
//                Toast.makeText(context,"身份证解析失败",Toast.LENGTH_LONG).show();
//                Log.d("MainActivity","文字解析失败:" + ret);
//            }

            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            readIDCard(context);
        }).start();
    }



//    public void btnGetCardInfoClicked(View arg0)  {
//        //获取社保卡信息
//
//        //EF05
////        String CardSlot =  m_CardSlot.getSelectedItem().toString().trim();
//        int iSlot = 0x31;
//        //public static native int ReadSIIssuerInfo(int icdev, int uSlot,byte[] pData);
//        byte[] pData = new byte[256];
////        long stime = SystemClock.uptimeMillis();
//        int ret = NativeReader.ReadSIIssuerInfo(NativeReader.icdev,iSlot,pData);
////        stime = SystemClock.uptimeMillis() - stime;
//        if(ret == 0)
//        {
//            //EF06，三代卡不认证是无法读取个人信息的。
//            //public static native int ReadSIPersonalInfo(int icdev,int uSlot,byte[] pData);
//            String rDataE5 = null;
//            try {
//                rDataE5 = new String(pData,"gb18030").trim();
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }
//            //stime = SystemClock.uptimeMillis();
////            ShowTips(1,"EF05耗时:" + stime);
////            ShowTips(1,"读取成功，EF05:" + rDataE5);
//
////            byte[] pData2 = new byte[256];
////            stime = SystemClock.uptimeMillis();
////            ret = NativeReader.ReadSIPersonalInfo(NativeReader.icdev,iSlot,pData2);
////            stime = SystemClock.uptimeMillis() - stime;
////            if(ret == 0)
////            {
////                String rDataE6 = null;
////                try {
////                    rDataE6 = new String(pData2,"gb18030").trim();
////                } catch (UnsupportedEncodingException e) {
////                    e.printStackTrace();
////                }
//////                ShowTips(1,"EF06耗时:" + stime);
//////                ShowTips(1,"读取成功，EF06:" +  rDataE6);
////            }
////            else {
//////                ShowTips(1,"EF06读取失败,返回值：" + ret);
////            }
//        }else{
//            //EF05读取失败
//            Log.d("MainActivity","EF05读取失败,返回值：" + ret);
////            ShowTips(1,"EF05读取失败,返回值：" + ret);
//        }
//        //stime = SystemClock.uptimeMillis() - stime;
//        //ShowTips(1,"显示耗时:" + stime);
//    }


    public void closeDev(){
        if (NativeReader.icdev > 0){
            NativeReader.ICReaderClose(NativeReader.icdev);
        }
    }
}
